package ca.jsbr.as2js_lib.utils 
{
	import ca.jsbr.as2js_lib.event.EventDispatcher;
	import ca.jsbr.as2js_lib.event.MouseJSEvent;
	import ca.jsbr.as2js_lib.utils.generic.TagUtils;
	import ca.jsbr.as2js_lib.utils.geom.Point;
	import ca.jsbr.as2js_lib.utils.geom.Rect;
	import flash.events.Event;
	import flash.utils.Dictionary;
	import js.element.HTMLElement;
	import js.event.MouseEvent;
	/**
	 * ...
	 * @author ...
	 */
	public class MouseManager extends EventDispatcher 
	{
		
		static public const CLICK:String = "click";
		static public const MOUSE_MOVE:String = "mousemove";
		static public const MOUSE_DOWN:String = "mousedown";
		static public const MOUSE_UP:String = "mouseup";
		static public const MOUSEWHEEL:String = "mousewheel";
		
		static private var _instance:MouseManager;
		private var _tag:HTMLElement;
		private var _tagPosition:Rect;
		private var _viewEvent:Dictionary;
		private var _stageMouse:Point;
		private var _up:int;
		private var _down:int;
		private var _click:int;
		private var _move:Boolean;
		private var _wheelDelta:Number;
		private var _cursor:String;
		
		public function MouseManager() 
		{
			_tagPosition = new Rect();
			_viewEvent = new Dictionary();
		}
		
		public function start(tag:HTMLElement):void
		{
			_tag = tag;
			tag.addEventListener(MOUSE_MOVE, onMouseMove);
			tag.addEventListener(MOUSE_DOWN, onMouseDown);
			tag.addEventListener(MOUSE_UP, onMouseUp);
			tag.addEventListener(CLICK, onMouseClick);
			tag.addEventListener(MOUSEWHEEL, onMouseWheel);
			_tagPosition = TagUtils.getCoord(tag);
		}
		
		
		
		public function get stageMouse():Point
		{
			return _stageMouse;
		}
		
		public function get action():Boolean
		{
			return _move || _down || _up;
		}
		
		public function get wheelDelta():Number 
		{
			return _wheelDelta;
		}
		
		public function set wheelDelta(value:Number):void 
		{
			_wheelDelta = value;
		}
		
		public function get move():Boolean 
		{
			return _move;
		}
		
		public function set move(value:Boolean):void 
		{
			_move = value;
		}
		
		public function get click():int 
		{
			return _click;
		}
		
		public function set click(value:int):void 
		{
			_click = value;
		}
		
		public function get down():int 
		{
			return _down;
		}
		
		public function set down(value:int):void 
		{
			_down = value;
		}
		
		public function get up():int 
		{
			return _up;
		}
		
		public function set up(value:int):void 
		{
			_up = value;
		}
		
		public function get cursor():String 
		{
			return _cursor;
		}
		
		public function set cursor(value:String):void 
		{
			_cursor = value;
			_tag.style.cursor = value;
		}
		


		public function stop():void
		{
			_tag.removeEventListener(MOUSE_MOVE, onMouseMove);
			_tag.removeEventListener(MOUSE_DOWN, onMouseDown);
			_tag.removeEventListener(MOUSE_UP, onMouseUp);
			_tag.removeEventListener(CLICK, onMouseClick);
		}
		
		
		public function postRender():void
		{
			_down = 0;
			_up = 0;
			_click = 0;
			_wheelDelta = 0;
			_move = false;
		}
		
		
		private function onMouseWheel(e:MouseEvent):void 
		{
			_wheelDelta = e.wheelDelta;
		}
		
		public function onMouseMove(e:MouseEvent):void
		{
			_move = true;
			var px:int = e.offsetX;
			var py:int = e.offsetY;
			if (px == undefined) {
				px = e.layerX - _tagPosition.x;
				py = e.layerY - _tagPosition.y;
			}
			_stageMouse = new Point(px, py);
			dispatchEvent(new MouseJSEvent(MouseJSEvent.MOUSE_MOVE, px, py));
		}
		
		private function onMouseClick(e:Event):void 
		{
			_click = e.which;
			if (e.offsetX == undefined)
				dispatchEvent(new MouseJSEvent(MouseJSEvent.MOUSE_CLICK, e.layerX-_tagPosition.x, e.layerY-_tagPosition.y));
			else
				dispatchEvent(new MouseJSEvent(MouseJSEvent.MOUSE_CLICK, e.offsetX, e.offsetY));
		}
		
		private function onMouseUp(e:Event):void 
		{
			_up = e.which;
			if (e.offsetX == undefined)
				dispatchEvent(new MouseJSEvent(MouseJSEvent.MOUSE_UP, e.layerX - _tagPosition.x, e.layerY - _tagPosition.y));
			else
				dispatchEvent(new MouseJSEvent(MouseJSEvent.MOUSE_UP, e.offsetX, e.offsetY));
		}
		
		private function onMouseDown(e:Event):void 
		{
			_down = e.which;
			if (e.offsetX == undefined)
				dispatchEvent(new MouseJSEvent(MouseJSEvent.MOUSE_DOWN, e.layerX-_tagPosition.x, e.layerY-_tagPosition.y));
			else
				dispatchEvent(new MouseJSEvent(MouseJSEvent.MOUSE_DOWN, e.offsetX, e.offsetY));
		}
		
		static public function getInstance():MouseManager 
		{
			if (!_instance)
				_instance = new MouseManager();
			return _instance;
		}
	}

}